/*
 * Flashlib - QB9 common Flash library
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package com.qb9.flashlib.input
{
	import flash.events.KeyboardEvent;
	import flash.ui.Keyboard;
	
	/**
	 * Utility class to convert Keyboard keys aliases (up,down,etc)
	 * to their equivalent key codes as well as adding modifiers (ctrl,shift,alt).
	 */
	
	public class Shortcut
	{
		private static const FIX : Object = {
			control: 'ctrl',
			pageup: 'page_up',
			pagedown:'page_down',
			esc:'escape',
			'`':'À'
			// There're more...
		};
		
		public static const NO_CODE	:int = -1;
		
		public static const SHIFT	: int = 0x1;
		public static const CTRL	: int = 0x2;
		public static const ALT		: int = 0x4;
		
		private var code:int;
		private var flags:int;
		
		public function Shortcut(str:String = '')
		{
			digest(str);
		}
		
		public function digest(str:String):void
		{
			code = NO_CODE;
			flags = 0;
			
			for each(var key:String in str.split(/[ +]+/))
			{
				if (!key)
					continue;

				key = fix(key);

				// ctrl | alt | shift
				if (key in Shortcut)
					flags |= Shortcut[key];
				// custom key
				else
					code = toKeyCode(key);
			}
		}
		
		// used to index handlers
		public function get uid():String
		{
			return code + '|' + flags;
		}
		
		// It's an Object so it can handle both KeyboardEvent and MouseEvent
		public static function fromEvent(e:Object):Shortcut
		{
			var shortcut:Shortcut = new Shortcut();

			// generate an integer from the 3 booleans using bits 
			if (e.shiftKey) shortcut.flags |= SHIFT;
			if (e.ctrlKey)  shortcut.flags |= CTRL;
			if (e.altKey)   shortcut.flags |= ALT;
			
			if (e is KeyboardEvent)
				shortcut.code = e.keyCode;
			
			return shortcut;
		}
		
		public static function fix(key:String):String
		{
			var lower:String = key.toLowerCase();
			return (lower in FIX ? String(FIX[lower]) : key).toUpperCase();
		}
		
		/**
		 * Converts an item from the following groups of keys to their key code.
		 * The key is case insensitive.
		 * <ul>
		 * 	<li>Characters (a-z)</li>
		 * 	<li>Numbers (0-9)</li>
		 * 	<li>All the codes stored on flash.ui.Keyboard</li>
		 *	<li>Other single characters (&amp;, etc.)</li>
		 * </ul>
		 * 
		 * @see flash.ui.Keyboard
		 */
		
		public static function toKeyCode(key:String):int
		{
			key = fix(key);

			if (key in Keyboard)
				return Keyboard[key];

			// letter or number
			if (key.length === 1)
				return key.charCodeAt(0);
			
			return -1;
		}

	}
}
